package com.neusoft.utils.tpl.res;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.neusoft.utils.encrypt.MD5Util;
import com.neusoft.utils.file.FileUtils;
import com.neusoft.utils.res.compressor.TResCompressorUtils;
import com.neusoft.utils.string.StringUtil;
import com.neusoft.utils.tpl.DirectiveUtils;
import com.neusoft.utils.tpl.bean.ResBean;
import com.neusoft.utils.tpl.bean.ResCacheBean;
import com.neusoft.utils.tpl.help.ReadJsonToMap;
import com.neusoft.utils.tpl.help.ResCache;
import com.neusoft.utils.web.RequestUtils;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

/**
 * 
 *
 * @author von_change@163.com
 * @date 2015年12月4日 下午12:56:33
 * @since 1.0
 */
public class CssAllMinDirective implements TemplateDirectiveModel {
	private String charset = "UTF-8";
	private String cssFolder ="/css/";//"nginx/files/enroll/res/css/";SystemConfig.getProperty("res.gen")+
	public static final String PARAM_SRC = "src";

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
		String result = "";
		StringBuffer sb = new StringBuffer();
		StringBuffer identifySb = new StringBuffer();
		Long sumTime=new Long(0);
		String src = DirectiveUtils.getString(PARAM_SRC, params);
		HttpServletRequest req = RequestUtils.getRequest();
		String base = req.getContextPath();
		String thisUrl=RequestUtils.getUrl(req);
		Map<String, String> configMap = ReadJsonToMap.read(getFile(req,"commonConfig/css.json"));
		String[] cssSrcs = src.split(",");
		List<ResBean> resList = new ArrayList<ResBean>();
		for (String cssStr : cssSrcs) {
			if (null == configMap.get(cssStr)) {			
				String cssPath = RequestUtils.getWebRealPath(req,cssStr);
				File cssFile = new File(cssPath);
				if (!cssFile.exists()) {
					env.getOut().append(result);
					return;
				}
				Long time = cssFile.lastModified();
				resList.add(new ResBean().setPath(cssStr).setTime(time).setFile(cssFile));
				identifySb.append(cssStr);
				sumTime+=time;
			} else {
				String[] cssSubSrcs = configMap.get(cssStr).split(",");
				for (String cssSubSrc : cssSubSrcs) {				
					String cssPath = RequestUtils.getWebRealPath(req,cssSubSrc);
					File cssFile = new File(cssPath);
					if (!cssFile.exists()) {
						env.getOut().append(result);
						return;
					}
					Long time = cssFile.lastModified();
					resList.add(new ResBean().setPath(cssSubSrc).setTime(time).setFile(cssFile));
					identifySb.append(cssStr);
					sumTime+=time;
				}
			}
		}
		boolean orgFlag = false;
		String s = req.getQueryString();
		if (null != s && !StringUtil.isBlank(s)) {
			if (s.endsWith("@")||ResCache.model.equals("debug")) {
				orgFlag = true;
			}
		}
		if (!orgFlag) {
			String thisUrlMd=MD5Util.getMD5(thisUrl);
			String md5 = thisUrlMd+"/"+MD5Util.getMD5(identifySb.toString());
			String cssFilePath = cssFolder + md5 +"-"+sumTime.toString()+ ".css";
			File minCssFile = new File(RequestUtils.getWebRealPath(req,cssFilePath));
			if (!minCssFile.exists()) {
				for (ResBean resBean : resList) {
					//单独生成做缓存
					sb.append("/*! ").append(resBean.getPath()).append(" */").append("\r\n").append(getMinCss(resBean)).append("\r\n ");
				}
				String cssStr=sb.toString();
				FileUtils.writeStringToFile(minCssFile, cssStr, charset);
			}
			result = StringUtil.format("<link rel=\"stylesheet\" href=\"{0}/{1}\">\r\n", base, cssFilePath);
		} else {
			result = renderOrgJsList(resList, base);
		}
		env.getOut().append(result);
	}
	private String getMinCss(ResBean resBean){
		ResCacheBean resCacheBean=ResCache.resCacheMap.get(resBean.getPath());
		if(null==resCacheBean||resCacheBean.getTime().longValue()!=resBean.getTime().longValue()){
			//更新缓存
			String sb = "";
			try {
				sb = FileUtils.readFileToString(resBean.getFile(), charset);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			String cssStr="";
			if(resBean.getPath().endsWith(".min.css")){
				cssStr=sb.toString();
			}else{
				try {
					cssStr=TResCompressorUtils.cssCompressor(sb);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			ResCache.resCacheMap.put(resBean.getPath(), new ResCacheBean().setContent(cssStr).setTime(resBean.getTime()));
		}
		return ResCache.resCacheMap.get(resBean.getPath()).getContent();
	}
	private String renderOrgJsList(List<ResBean> resList, String base) {
		StringBuffer resultSb = new StringBuffer();
		for (ResBean resBean : resList) {
			// <link rel="stylesheet" href="applySquare.css">
			resultSb.append(StringUtil.format("<link rel=\"stylesheet\" href=\"{0}/{1}?v={2}\">", base, resBean.getPath(),resBean.getTime().toString())).append("\r\n");
		}
		return resultSb.toString();
	}


	private File getFile(HttpServletRequest req,String path) {
		return new File(RequestUtils.getWebRealPath(req,path));
	}

}
